home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-19  |  30.7 KB  |  1,326 lines

  1. // #define    DEBUG
  2. /*
  3.     ARTemis (Graphic Editor for FM-TOWNS)
  4.     (c) MATSUUCHI Ryosuke 1992,1993
  5.  
  6.     menu.c
  7.  
  8.     メニュー処理を行う関数群
  9.  
  10.         menu_init
  11.         menu_end
  12.     各種取得関数
  13.         menu_plt
  14.         menu_ifdisp
  15.         menu_getcurmenu
  16.         menu_getmenuxy
  17.         menu_getbuttonxy
  18.         menu_where                メニュー内座標の機能の判定
  19.         menu_getifdisplay
  20.     メニュー
  21.         menu_disp                メニューの表示
  22.         menu_dispxy                メニューの表示(位置指定あり)
  23.         menu_erase                メニューの消去
  24.         void    menu_settitle(MENU *m, char *title)
  25.         int        menu_addbutton(MENU *m, BUTTON *b)
  26.         int        menu_addscrollbar(MENU *m, SCROLLBAR *s)
  27.         int        menu_addselector(MENU *m, SEL *s)
  28.         void    menu_clearselector(MENU *m)
  29.         menu_move
  30.     ボタン
  31.         BUTTON    *menu_button_new(void)
  32.         void    menu_button_delete(BUTTON *b)
  33.         void    menu_button_setid(BUTTON *b,int id)
  34.         BUTTON    *menu_button(MENU *menu, int id)
  35.         // BUTTON    *menu_button_getfirst(MENU *m);
  36.         // BUTTON    *menu_button_getnext(MENU *m);
  37.         void    menu_button_setxy(BUTTON *b, int x, int y)
  38.         void    menu_button_setvar(BUTTON *b, int var)
  39.     スクロールバー
  40.         SBAR    *menu_scrollbar_new(void)
  41.         void    menu_scrollbar_delete(SBAR *s)
  42.         void    menu_scrollbar_setid(SBAR *s,int id)
  43.         SBAR    *menu_scrollbar(MENU *m, int id)
  44.         void    menu_scrollbar_setxy(SBAR *s,int x,int y)
  45.         void    menu_scrollbar_getxy(SBAR *s,int*x,int*y,int*len)
  46.         void    menu_scrollbar_setfunc(SBAR *s, void (*func)())
  47.         menu_scrollbar_getvar
  48.         menu_scrollbar_setvar
  49.         menu_scrollbar_setallsize
  50.         menu_scrollbar_setdispsize
  51.         menu_touchscrollbar        スクロールバーをクリック/ドラッグした時の処理
  52.         menu_drawscrollbar
  53.         menu_makeupscrollbar    スクロールバー表示の更新
  54.     選択子
  55.         SEL        *menu_selector_new(void)
  56.         void    menu_selector_delete(SEL *s)
  57.         void    menu_selector_setid(SEL *s, int id)
  58.         SEL        *menu_selector(MENU *m, int id)
  59.         int        menu_selector_addelement(SEL *s, SEL_E *e)
  60.         int        menu_selector_getvar(SEL *s)
  61.         void    menu_selector_setvar(SEL *s, int n)
  62.         void    menu_selector_makeup(SEL *sp)
  63.         選択要素
  64.             SEL_E    *menu_selector_element_new(void)
  65.             void    menu_selector_element_delete(SEL_E *e)
  66.             void    menu_selector_element_setid(SEL_E *e, int id)
  67.             SEL_E    *menu_selector_element(SEL *s,int id)
  68.             SEL_E    *menu_selector_element_getfirst(SEL *s)
  69.             SEL_E    *menu_selector_element_getnext(SEL *s)
  70.             void    menu_selector_element_setxy(SEL_E *e,int x,int y)
  71.             void    menu_selector_element_setstr(SEL_E *e,char *s)
  72.             void    menu_selector_element_setavail(SEL_E *e,bool f)
  73.         menu_touchselector
  74.     メニュー上の描画
  75.         menu_putstr                メニュー内への文字列の表示
  76.         menu_buttonputstr        ボタン内への文字列の表示
  77.         menu_drawbox            陰影つき枠の表示
  78.     メニューへのデータの設定・解除
  79.         menu_setdata
  80.         menu_getdata
  81.         menu_cleardata
  82. */
  83.  
  84. #define    NEWMENU    1
  85.  
  86. #define    MODULE_MENU
  87.  
  88. #include <stdio.h>
  89. #include <string.h>
  90. #include <malloc.h>
  91.  
  92. #include "ge.h"
  93. #include "dispman.h"
  94.  
  95. #define    Cwhite            DMgetmenuplt(White)
  96. #define    Cblack            DMgetmenuplt(Black)
  97. #define    Cgray            DMgetmenuplt(Gray)
  98. #define    Clightgray        DMgetmenuplt(LightGray)
  99. #define    Cdarkgray        DMgetmenuplt(DarkGray)
  100. #define    Cyellow            DMgetmenuplt(Yellow)
  101. #define    Cblack0            DMgetmenuplt(Black0)
  102. #define    Ctransparent    DMgetmenuplt(Transparent)
  103. #define    Ccolorless        DMgetmenuplt(Colorless)
  104. #define    Clatticecolor    DMgetmenuplt(LatticeColor)
  105. #define    Cmenu            DMgetmenuplt(COL_menu)
  106. #define    Cmenu2            DMgetmenuplt(COL_menu2)
  107. #define    Cmenulight        DMgetmenuplt(COL_menuLight)
  108. #define    Cmenushade        DMgetmenuplt(COL_menuShade)
  109. #define    Cmenustring        DMgetmenuplt(COL_menuString)
  110. #define    Ccsrlight        DMgetmenuplt(COL_cursorLight)
  111. #define    Ccsrdark        DMgetmenuplt(COL_cursorDark)
  112. #define    ColM            Cmenu
  113. #define    ColM2            Cmenu2
  114. #define    ColL            Cmenulight
  115. #define    ColS            Cmenushade
  116.  
  117. #define    MENUNUM    3
  118. static    MENU    *menulist[MENUNUM];
  119. static    MENU    *menulist_bak[MENUNUM];
  120.  
  121.  
  122. /*--------------------------------------------------------*/
  123. /*                モジュールの初期化/終了                */
  124. /*--------------------------------------------------------*/
  125.  
  126.  
  127. int menu_init()
  128. {
  129.     PRINT("menu_init begin\n");
  130.     int i;
  131.     for (i=0; i<MENUNUM; i++)
  132.         menulist[i] = NULL;
  133.     PRINT("menu_init end\n");
  134.     return 0;
  135. }
  136.  
  137.  
  138. void menu_end()
  139. {
  140. }
  141.  
  142.  
  143. /*--------------------------------------------------------*/
  144. /*                      各種取得関数                      */
  145. /*--------------------------------------------------------*/
  146.  
  147.  
  148. int menu_plt(int n)
  149. {
  150.     return DMgetmenuplt(n);
  151. }
  152.  
  153.  
  154. int menu_ifdisp()
  155. {
  156.     if (menulist[0] != NULL)
  157.         return 1;
  158.     else
  159.         return 0;
  160. }
  161.  
  162.  
  163. MENU* menu_getcurmenu()
  164. {
  165.     return menulist[0];
  166. }
  167.  
  168.  
  169. void menu_getmenuxy(MENU *menu, int *x, int *y, int *xlen, int *ylen)
  170. {
  171.     if (menu == NULL)
  172.         menu = menulist[0];
  173.     KNOW(menu!=NULL);
  174.     if (x != NULL)
  175.         *x = menu->x;
  176.     if (y != NULL)
  177.         *y = menu->y;
  178.     if (xlen != NULL)
  179.         *xlen = menu->xlen;
  180.     if (ylen != NULL)
  181.         *ylen = menu->ylen;
  182.     return;
  183. }
  184.  
  185.  
  186. void menu_getbuttonxy(MENU *menu,int btnnum,int *x,int *y,int *xlen,int *ylen)
  187. {
  188.     if (menu == NULL)
  189.         menu = menulist[0];
  190.     KNOW(menu!=NULL);
  191.     BUTTON *bp = menu_button(menu,btnnum);
  192.     if (x != NULL)
  193.         *x = menu->x + bp->x;
  194.     if (y != NULL)
  195.         *y = menu->y + bp->y;
  196.     if (xlen != NULL)
  197.         *xlen = bp->xlen;
  198.     if (ylen != NULL)
  199.         *ylen = bp->ylen;
  200. }
  201.  
  202.  
  203. bool menu_getifdisplay(MENU *menu)
  204. {
  205.     if (menu == NULL)
  206.         menu = menulist[0];
  207.     if (menu==NULL)
  208.         return NO;
  209.     else
  210.         return menu->display;
  211. }
  212.  
  213.  
  214. int menu_where(int x,int y,MENU *menu, int *ax,int *ay,SCROLLBAR **sbarp)
  215. {
  216.     if (menu->x <= x && x <= menu->x+menu->xlen-1
  217.      && menu->y <= y && y <= menu->y+menu->ylen-1)
  218.     {
  219.         int mx,my;
  220.         mx = x-menu->x;
  221.         my = y-menu->y;
  222.         BUTTON *ip;  int an;
  223.             // アイテムリストを逆順にたどり、 判定していく
  224.         for (ip = menu->buttonlist, an=0;  ip!=NULL && ip->x>=0;  ip++,an++)
  225.             ;
  226.         for (an--,ip--;  an>=0;  an--,ip--)
  227.         {
  228.             if (!ip->noselect&&ip->x <= mx && mx < ip->x+ip->xlen &&
  229.              ip->y <= my && my < ip->y+ip->ylen)
  230.             {
  231.                 if(ax!=NULL) *ax = mx - ip->x;
  232.                 if(ay!=NULL) *ay = my - ip->y;
  233.                 return ip->id;
  234.             }
  235.         }
  236.         SCROLLBAR *sp;
  237.         for (sp = menu->sbarlist;  sp!=NULL && sp->x>=0;  sp++)
  238.         {
  239.             if (sp->type == barHORI)
  240.             {
  241.                 if (sp->x <= mx && mx < sp->x + sp->len &&
  242.                  sp->y <= my && my < sp->y + 14)
  243.                 {
  244.                     if (ax!=NULL) *ax = mx - sp->x;
  245.                     if (ay!=NULL) *ay = my - sp->y;
  246.                     if(sbarp!=NULL)
  247.                         *sbarp=sp;
  248.                     return itemScrollBar;
  249.                 }
  250.             }
  251.             else
  252.             {
  253.                 if (sp->x <= mx && mx < sp->x + 14 &&
  254.                  sp->y <= my && my < sp->y + sp->len)
  255.                 {
  256.                     if(ax!=NULL) *ax = mx - sp->x;
  257.                     if(ay!=NULL) *ay = my - sp->y;
  258.                     if(sbarp!=NULL)
  259.                         *sbarp=sp;
  260.                     return itemScrollBar;
  261.                 }
  262.             }
  263.         }
  264.         SELECTOR *sel;
  265.         for (sel = menu->sellist;  sel != NULL && sel->var >= 0;  sel++)
  266.         {
  267.             SELECTOR_ELEMENT *seli;
  268.             for (seli=sel->elist; seli!=NULL&&seli->x>=0; seli++)
  269.             {
  270.                 if (seli->x <= mx && mx <= seli->x + 14 + 6*strlen(seli->str) &&
  271.                     seli->y <= my && my <= seli->y + 11)
  272.                 {
  273.                     return itemSelector;
  274.                 }
  275.             }
  276.         }
  277.         for (sel = menu->d_sellist;  sel != NULL;  sel=sel->next)
  278.         {
  279.             SELECTOR_ELEMENT *seli;
  280.             for (seli=sel->d_elist; seli!=NULL; seli=seli->next)
  281.             {
  282.                 if (seli->x<=mx&&mx <= seli->x + 14 + 6*strlen(seli->str) &&
  283.                     seli->y<=my&&my<= seli->y + 11)
  284.                 {
  285.                     return itemSelector;
  286.                 }
  287.             }
  288.         }
  289.         if (my<16)
  290.         {
  291.             if(ax!=NULL) *ax = mx;
  292.             if(ay!=NULL) *ay = my;
  293.             return itemMoveMenu;
  294.         }
  295.         return itemOther;
  296.     }
  297.     else
  298.         return OutOfMenu;
  299. }
  300.  
  301.  
  302. /*--------------------------------------------------------*/
  303. /*                         ボタン                         */
  304. /*--------------------------------------------------------*/
  305.  
  306.  
  307. BUTTON    *menu_button_new(void)
  308. {
  309.     BUTTON *b;
  310.     b = malloc(sizeof(BUTTON));
  311.     if (b==NULL) return NULL;
  312.     memset(b,0,sizeof(BUTTON));
  313.     return b;
  314. }
  315.  
  316.  
  317. void    menu_button_delete(BUTTON *b)
  318. {
  319.     free(b);
  320. }
  321.  
  322.  
  323. void    menu_button_setid(BUTTON *b,int id)
  324. {
  325.     b->id = id;
  326. }
  327.  
  328.  
  329. BUTTON    *menu_button(MENU *menu, int id)
  330. {
  331.     BUTTON *bp;
  332.     for (bp=menu->buttonlist; bp!=NULL && bp->x>=0; bp++)
  333.         if (bp->id == id)
  334.             return bp;
  335.     for (bp=menu->d_buttonlist; bp!=NULL; bp=bp->next)
  336.         if (bp->id == id)
  337.             return bp;
  338.     return NULL;
  339. }
  340.  
  341.  
  342. void menu_button_setxy(BUTTON *b, int x, int y)
  343. {
  344.     b->x = x;
  345.     b->y = y;
  346. }
  347.  
  348.  
  349. void menu_button_setvar(BUTTON *b, int var)
  350. {
  351.     b->var = var;
  352. }
  353.  
  354.  
  355. /*--------------------------------------------------------*/
  356. /*                     スクロールバー                     */
  357. /*--------------------------------------------------------*/
  358.  
  359.  
  360. #define    BARH    12
  361. #define    SWW        12
  362.  
  363.  
  364. static void menu_dispbarvar(SCROLLBAR *sp)
  365. {
  366.     int bx,by,blen;
  367.     menu_getmenuxy(NULL, &bx, &by, NULL, NULL);
  368.     bx += sp->x, by += sp->y, blen = sp->len;
  369.     char nbuf[10];
  370.     int l = sp->numofs + sp->allsize - sp->dspsize;
  371.     if (l < 10)
  372.         sprintf(nbuf,"%1d",sp->numofs + sp->dsppos);
  373.     else if (10 <= l && l < 100)
  374.         sprintf(nbuf,"%2d",sp->numofs + sp->dsppos);
  375.     else if (100 <= l && l < 1000)
  376.         sprintf(nbuf,"%3d",sp->numofs + sp->dsppos);
  377.     else
  378.         sprintf(nbuf,"%4d",sp->numofs + sp->dsppos);
  379.     if (sp->type == barHORI)
  380.     {
  381.         if (sp->dispnum)
  382.         {
  383.          grboxfill(bx-4-6*strlen(nbuf),by,6*strlen(nbuf),12,Cmenu,DrawNORMAL);
  384.          ARTputstr12(bx-4-6*strlen(nbuf), by, nbuf, Cmenustring, Cmenu);
  385.         }
  386.     }
  387.     else
  388.     {
  389.         if (sp->dispnum)
  390.         {
  391.          grboxfill(bx+(BARH-6*strlen(nbuf))/2,by+sp->len+1,6*strlen(nbuf),12,
  392.                     Cmenu,DrawNORMAL);
  393.          ARTputstr12(bx+(BARH-6*strlen(nbuf))/2,by+sp->len+1,nbuf,
  394.                       Cmenustring, Cmenu);
  395.         }
  396.     }
  397. }
  398.  
  399.  
  400. static void _menu_makeupscrollbar(SCROLLBAR *sp, bool barnormal)
  401. {
  402.     if (sp->len <= 0)
  403.         return;
  404.     int bx,by,blen;
  405.     void drawbox(int x,int y,int xlen,int ylen)
  406.     {
  407.         if (barnormal)
  408.         {
  409.             ghline(x, x+xlen-1, y, Cmenulight, DrawNORMAL);
  410.             gvline(x, y, y+ylen-1, Cmenulight, DrawNORMAL);
  411.             ghline(x+1, x+xlen-1, y+ylen-1, Cmenushade, DrawNORMAL);
  412.             gvline(x+xlen-1, y+1, y+ylen-1, Cmenushade, DrawNORMAL);
  413.         }
  414.         else
  415.             grboxline(x,y,xlen,ylen,Cblack,DrawNORMAL);
  416.     }
  417.     menu_getmenuxy(NULL, &bx, &by, NULL, NULL);
  418.     bx += sp->x;
  419.     by += sp->y;
  420.     blen = sp->len;
  421.     int p,len;
  422.     if (sp->dspsize < sp->allsize)
  423.     {
  424.         if (!sp->inv)
  425.             p=((blen-SWW*2)*sp->dsppos)/sp->allsize;
  426.         else
  427.             p=((blen-SWW*2)*(sp->allsize-sp->dspsize-sp->dsppos))/sp->allsize;
  428.         len = ((blen-SWW*2) * sp->dspsize) / sp->allsize;
  429.     }
  430.     else
  431.     {
  432.         p = 0;
  433.         len = blen-SWW*2;
  434.     }
  435.     if (sp->type == barHORI)
  436.     {
  437.         grboxfill(bx+SWW,by+1,blen-SWW*2,BARH-2,Cmenu,DrawNORMAL);
  438.         drawbox(bx+SWW+p,by+1,len,BARH-2);
  439.         menu_dispbarvar(sp);
  440.     }
  441.     else
  442.     {
  443.         grboxfill(bx+1,by+SWW,SWW-2,blen-SWW*2,Cmenu,DrawNORMAL);
  444.         drawbox(bx+1,by+SWW+p,BARH-2,len);
  445.         menu_dispbarvar(sp);
  446.     }
  447. }
  448.  
  449.  
  450. void menu_makeupscrollbar(SCROLLBAR *sp)
  451. {
  452.     if (menu_getifdisplay(NULL))
  453.         _menu_makeupscrollbar(sp, YES);
  454. }
  455.  
  456.  
  457. SCROLLBAR *menu_scrollbar(MENU *menu, int id)
  458. {
  459.     SCROLLBAR *sp;
  460.     for (sp=menu->sbarlist; sp!=NULL&&sp->x>=0; sp++)
  461.         if(sp->id == id) return sp;
  462.     for (sp=menu->d_sbarlist; sp!=NULL; sp=sp->next)
  463.         if(sp->id == id) return sp;
  464.     return NULL;
  465. }
  466.  
  467.  
  468. void    menu_scrollbar_setxy(SBAR *s,int x,int y)
  469. {
  470.     s->x = x;
  471.     s->y = y;
  472. }
  473.  
  474.  
  475. void    menu_scrollbar_getxy(SBAR *s,int*x,int*y,int*len)
  476. {
  477.     if (x!=NULL) *x=menuX+s->x;
  478.     if (y!=NULL) *y=menuY+s->y;
  479.     if (len!=NULL) *len=s->len;
  480. }
  481.  
  482.  
  483. void    menu_scrollbar_setfunc(SBAR *s, void (*func)())
  484. {
  485.     s->dspfunc = func;
  486. }
  487.  
  488.  
  489. int menu_scrollbar_getvar(SCROLLBAR *sp)
  490. {
  491.     return sp->numofs + sp->dsppos;
  492. }
  493.  
  494.  
  495. void menu_scrollbar_setvar(SCROLLBAR *sp, int dsppos)
  496. {
  497.     sp->dsppos = _lim(dsppos-sp->numofs, 0, sp->allsize - sp->dspsize);
  498.     menu_makeupscrollbar(sp);
  499. }
  500.  
  501.  
  502. void menu_scrollbar_setallsize(SCROLLBAR *sp, int allsize)
  503. {
  504.     sp->allsize = allsize;
  505.     sp->dsppos = _lim(sp->dsppos, 0, sp->allsize - sp->dspsize);
  506.     if(sp->dspsize!=0)
  507.         menu_makeupscrollbar(sp);
  508. }
  509.  
  510.  
  511. void menu_scrollbar_setdispsize(SCROLLBAR *sp, int dispsize)
  512. {
  513.     sp->dspsize = dispsize;
  514.     sp->dsppos = _lim(sp->dsppos, 0, sp->allsize - sp->dspsize);
  515.     if(sp->allsize!=0)
  516.         menu_makeupscrollbar(sp);
  517. }
  518.  
  519.  
  520. void menu_drawscrollbar(SCROLLBAR *sp)
  521. {
  522.     if (sp->len <= 0)
  523.         return;
  524.     int bx,by,blen;
  525.     menu_getmenuxy(NULL, &bx, &by, NULL, NULL);
  526.     bx += sp->x;
  527.     by += sp->y;
  528.     blen = sp->len;
  529.     if (sp->type == barHORI)
  530.     {
  531.         putpict(bx,by,Pleftsw);
  532.         putpict(bx+blen-SWW,by,Prightsw);
  533.         ghline(bx+SWW,bx+blen-SWW-1,by,Cmenushade,DrawNORMAL);
  534.         ghline(bx+SWW,bx+blen-SWW-1,by+BARH-1,Cmenulight,DrawNORMAL);
  535.     }
  536.     else
  537.     {
  538.         putpict(bx,by,Pupsw);
  539.         putpict(bx,by+blen-SWW,Pdownsw);
  540.         gvline(bx,by+SWW,by+blen-SWW-1,Cmenushade,DrawNORMAL);
  541.         gvline(bx+BARH-1,by+SWW,by+blen-SWW-1,Cmenulight,DrawNORMAL);
  542.     }
  543.     _menu_makeupscrollbar(sp,YES);
  544.     if (sp->dspfunc != NOFNC)
  545.         (*sp->dspfunc)(sp->dsppos);
  546. }
  547.  
  548.  
  549. void menu_touchscrollbar(SCROLLBAR *sp,int ax,int ay)
  550. {
  551.     if (sp->len <= 0)
  552.         return;
  553.     int mx,my;
  554.     menu_getmenuxy(NULL, &mx, &my, NULL, NULL);
  555.     void makeupBar(bool normalbar)
  556.     {
  557.         _menu_makeupscrollbar(sp, normalbar);
  558.         if (sp->dspfunc != NOFNC)
  559.             (*sp->dspfunc)(sp->dsppos);
  560.     }
  561.     void incdecPos(int dir)
  562.     {
  563.         if (dir == -1)
  564.             { if (sp->dsppos > 0)
  565.                 sp->dsppos--; }
  566.         else
  567.             { if (sp->dsppos+sp->dspsize < sp->allsize)
  568.                 sp->dsppos++; }
  569.         makeupBar(YES);
  570.         int iniwait;
  571.         iniwait = 150;
  572.         for (;;)
  573.         {
  574.             DMdispcsr(ms.x,ms.y);
  575.             ms_get(&ms);
  576.             DMerasecsr();
  577.             if (ms.btn1!=ON)
  578.                 break;
  579.             if (iniwait > 0)
  580.                 iniwait--;
  581.             else
  582.             {
  583.                 if (dir == -1)
  584.                   { if (sp->dsppos > 0)
  585.                         { sp->dsppos--;  makeupBar(YES); } }
  586.                 else
  587.                   { if (sp->dsppos < sp->allsize-sp->dspsize)
  588.                         { sp->dsppos++;  makeupBar(YES); } }
  589.             }
  590.         }
  591.     }
  592.     #define    BARLEN    (sp->len-SWW*2)
  593.     #define    FRAC(a,f1,f2)    ((2*(a)*(f1)+(f2))/((f2)*2))
  594.  
  595. #define    TOUCHBAR(_x,_y) {                                                      \
  596.     if (0<=a##_x && a##_x<SWW && 0<=a##_y && a##_y<BARH)                    \
  597.         incdecPos((!sp->inv ? -1 : 1));                                        \
  598.     else if (sp->len-SWW<=a##_x && a##_x<sp->len && 0<=a##_y && a##_y<BARH)    \
  599.         incdecPos((!sp->inv ? 1 : -1));                                        \
  600.     else                                                                    \
  601.     {                                                                        \
  602.         int p,len;                                                            \
  603.         void set_p_len(void)                                                \
  604.         {                                                                    \
  605.             if (sp->dspsize < sp->allsize)                                    \
  606.               { if (!sp->inv)                                                \
  607.                      p=FRAC(BARLEN,sp->dsppos, sp->allsize);                    \
  608.                 else                                                        \
  609.                     p=FRAC(BARLEN,sp->allsize-sp->dspsize-sp->dsppos,        \
  610.                            sp->allsize);                                    \
  611.                 len = FRAC(BARLEN, sp->dspsize,sp->allsize); }                \
  612.             else                                                            \
  613.               { p = 0;                                                        \
  614.                 len = BARLEN; }                                                \
  615.         }                                                                    \
  616.         set_p_len();                                                        \
  617.         if (a##_x < SWW+p || SWW+p+len <= a##_x)                            \
  618.         {                                                                    \
  619.             int cx = (ms._x-len/2)-(m##_x+sp->_x+SWW);                        \
  620.             /* cx = _lim(cx, 0, BARLEN-len); */                                \
  621.             sp->dsppos = FRAC(cx, sp->allsize, BARLEN);                        \
  622.             if (sp->inv)                                                    \
  623.                 sp->dsppos = sp->allsize - sp->dspsize - sp->dsppos;        \
  624.             sp->dsppos = _lim(sp->dsppos,0,sp->allsize-sp->dspsize);        \
  625.         }                                                                    \
  626.         set_p_len();                                                        \
  627.         int dx = a##_x - (SWW+p);                                            \
  628.         int cx;                                                                \
  629.         for (;;)                                                            \
  630.         {                                                                    \
  631.             cx = (ms._x - dx) - (m##_x + SWW + sp->_x);                        \
  632.             /* cx = _lim(cx, 0, BARLEN-len); */                                \
  633.             sp->dsppos = FRAC(cx, sp->allsize, BARLEN);                        \
  634.             if (sp->inv)                                                    \
  635.                 sp->dsppos = sp->allsize - sp->dspsize - sp->dsppos;        \
  636.             sp->dsppos = _lim(sp->dsppos, 0, sp->allsize-sp->dspsize);        \
  637.             makeupBar(NO);                                                    \
  638.             DMdispcsr(ms.x,ms.y);                                            \
  639.             do {                                                            \
  640.                 ms_get(&ms);                                                \
  641.             } while (ms.dx==0 && ms.dy==0 && ms.btn1==ON &&                    \
  642.                      key_read()==0);                                        \
  643.             DMerasecsr();                                                    \
  644.             if (ms.btn1!=ON)                                                \
  645.                 break;                                                        \
  646.         }                                                                    \
  647.         /* sp->dsppos = FRAC(cx, sp->allsize,BARLEN); */                    \
  648.         sp->dsppos = _lim(sp->dsppos, 0, sp->allsize - sp->dspsize);        \
  649.         makeupBar(YES);                                                        \
  650.     }                                                                        \
  651. }
  652. #
  653.  
  654.     if (sp->type == barHORI)
  655.     {
  656.         TOUCHBAR(x,y);
  657.     }
  658.     else
  659.     {
  660.         TOUCHBAR(y,x);
  661.     }
  662. }
  663.  
  664.  
  665. /*--------------------------------------------------------*/
  666. /*                         選択子                         */
  667. /*--------------------------------------------------------*/
  668.  
  669.  
  670. SEL        *menu_selector_new(void)
  671. {
  672.     SEL *s;
  673.     s = malloc(sizeof(SEL));
  674.     if(s==NULL) return NULL;
  675.     s->var = 0;
  676.     s->elist = 0;
  677.     s->next = NULL;
  678.     s->id = 0;
  679.     return s;
  680. }
  681.  
  682.  
  683. void    menu_selector_delete(SEL *s)
  684. {
  685.     free(s);
  686. }
  687.  
  688.  
  689. void    menu_selector_setid(SEL *s, int id)
  690. {
  691.     s->id = id;
  692. }
  693.  
  694.  
  695. SEL        *menu_selector(MENU *m, int id)
  696. {
  697.     SEL *s;
  698.     for(s=m->sellist; s!=NULL && s->var>=0; s++)
  699.         if(s->id==id) return s;
  700.     for(s=m->d_sellist; s!=NULL; s=s->next)
  701.         if(s->id==id) return s;
  702.     return NULL;
  703. }
  704.  
  705.  
  706. int        menu_selector_addelement(SEL *s, SEL_E *e)
  707. {
  708.     if (s->d_elist == NULL)
  709.         { s->d_elist = e; e->next = NULL; }
  710.     else {
  711.         SEL_E *ep;
  712.         for(ep=s->d_elist;ep->next!=NULL;ep=ep->next)
  713.             ;
  714.         ep->next = e; e->next = NULL;
  715.     }
  716.     return 0;
  717. }
  718.  
  719.  
  720. int        menu_selector_getvar(SEL *s)
  721. {
  722.     return s->var;
  723. }
  724.  
  725.  
  726. void    menu_selector_setvar(SEL *s, int n)
  727. {
  728.     s->var = n;
  729. }
  730.  
  731.  
  732. // 選択要素
  733.  
  734.  
  735. SEL_E    *menu_selector_element_new(void)
  736. {
  737.     SEL_E *s;
  738.     s = malloc(sizeof(SEL_E));
  739.     if(s==NULL) return NULL;
  740.     s->x = s->y = 0;
  741.     s->str = NULL;
  742.     s->available = YES;
  743.     s->next = NULL;
  744.     s->id = 0;
  745.     return s;
  746. }
  747.  
  748.  
  749. void    menu_selector_element_delete(SEL_E *e)
  750. {
  751.     free(e);
  752. }
  753.  
  754.  
  755. void    menu_selector_element_setid(SEL_E *e, int id)
  756. {
  757.     e->id = id;
  758. }
  759.  
  760.  
  761. SEL_E    *menu_selector_element(SEL *s,int id)
  762. {
  763.     SEL_E *ep;
  764.     for(ep=s->elist;ep!=NULL&&ep->x>=0;ep++)
  765.         if(ep->id==id) return ep;
  766.     for(ep=s->d_elist;ep!=NULL;ep=ep->next)
  767.         if(ep->id==id) return ep;
  768.     return NULL;
  769. }
  770.  
  771.  
  772. SEL_E    *menu_selector_element_getfirst(SEL *s)
  773. {
  774.     if(s==NULL) return NULL;
  775.     if(s->elist!=NULL)
  776.     {
  777.         s->cur_se = s->elist;
  778.         s->se_static = YES;
  779.     }
  780.     else
  781.     {
  782.         s->cur_se = s->d_elist;
  783.         s->se_static = NO;
  784.     }
  785.     return s->cur_se;
  786. }
  787.  
  788.  
  789. SEL_E    *menu_selector_element_getnext(SEL *s)
  790. {
  791.     if(s==NULL) return NULL;
  792.     if (s->cur_se == NULL)
  793.         return NULL;
  794.     if(s->se_static)
  795.     {
  796.         (s->cur_se)++; 
  797.         if(s->cur_se->x >= 0) return s->cur_se;
  798.         s->se_static = NO;
  799.         s->cur_se = s->d_elist;
  800.         return s->cur_se;
  801.     }
  802.     else
  803.     {
  804.         s->cur_se = s->cur_se->next;
  805.         return s->cur_se;
  806.     }
  807. }
  808.  
  809.  
  810. void    menu_selector_element_setxy(SEL_E *e,int x,int y)
  811. {
  812.     e->x = x,e->y=y;
  813. }
  814.  
  815.  
  816. void    menu_selector_element_setstr(SEL_E *e,char *s)
  817. {
  818.     e->str=s;
  819. }
  820.  
  821.  
  822. void    menu_selector_element_setavail(SEL_E *e,bool f)
  823. {
  824.     e->available = f;
  825. }
  826.  
  827.  
  828. static SEL_E *n2se(SEL *s, int n)
  829. {
  830.     SEL_E *e; int i;
  831.     for (e=menu_selector_element_getfirst(s),i=0;
  832.          e!=NULL;
  833.          e=menu_selector_element_getnext(s),i++)
  834.         if (i==n)
  835.             return e;
  836.     return NULL;
  837. }
  838.  
  839.  
  840. void menu_selector_makeup(SEL *sp)
  841. {
  842.     int mx,my;
  843.     if (!menu_ifdisp())
  844.         return;
  845.     MENU *menu = menu_getcurmenu();
  846.     menu_getmenuxy(menu, &mx, &my, NULL, NULL);
  847.     SEL_E *seli;  int var;
  848.     for (seli=menu_selector_element_getfirst(sp),var=0;
  849.          seli!=NULL;
  850.          seli=menu_selector_element_getnext(sp),var++)
  851.     {
  852.         if (var == sp->var)
  853.             putpict(mx+seli->x, my+seli->y, Pselecton);
  854.         else
  855.             putpict(mx+seli->x, my+seli->y, Pselectoff);
  856.     }
  857. }
  858.  
  859.  
  860. void menu_touchselector(MENU *menu)
  861. {
  862.     int mx,my;
  863.     menu_getmenuxy(menu, &mx, &my, NULL, NULL);
  864.     SELECTOR *sel;
  865.     for (sel = menu->sellist;  sel != NULL && sel->var >= 0;  sel++)
  866.     {
  867.         SEL_E *pre_seli = n2se(sel,sel->var);
  868.         SEL_E *seli;  int var;
  869.         for (seli=menu_selector_element_getfirst(sel),var=0;
  870.              seli!=NULL;
  871.              seli=menu_selector_element_getnext(sel),var++)
  872.         {
  873.             if (seli->x<=ms.x-mx && ms.x-mx<=seli->x+14+6*strlen(seli->str) &&
  874.                 seli->y<=ms.y-my && ms.y-my<=seli->y+11 && seli->available)
  875.             {
  876.                 putpict(mx+pre_seli->x, my+pre_seli->y, Pselectoff);
  877.                 putpict(mx+seli->x, my+seli->y, Pselecton);
  878.                 sel->var = var;
  879.             }
  880.         }
  881.     }
  882.     for (sel = menu->d_sellist;  sel != NULL;  sel=sel->next)
  883.     {
  884.         SEL_E *pre_seli = n2se(sel,sel->var);
  885.         SEL_E *seli;  int var;
  886.         for (seli=menu_selector_element_getfirst(sel),var=0;
  887.              seli!=NULL;
  888.              seli=menu_selector_element_getnext(sel),var++)
  889.         {
  890.             if (seli->x<=ms.x-mx && ms.x-mx<=seli->x+14+6*strlen(seli->str) &&
  891.                 seli->y<=ms.y-my && ms.y-my<=seli->y+11 && seli->available)
  892.             {
  893.                 putpict(mx+pre_seli->x, my+pre_seli->y, Pselectoff);
  894.                 putpict(mx+seli->x, my+seli->y, Pselecton);
  895.                 sel->var = var;
  896.             }
  897.         }
  898.     }
  899. }
  900.  
  901.  
  902. /*--------------------------------------------------------*/
  903. /*                    メニュー上の描画                    */
  904. /*--------------------------------------------------------*/
  905.  
  906.  
  907. // メニュー内に文字列を描画する
  908.  
  909.  
  910. void    menu_putstr(int ofsx, int ofsy, char *str, int type)
  911. // type : typeSTR, typeSTRe のいずれか
  912. {
  913.     if (str == NULL)
  914.         return;
  915.     int sx,sy;
  916.     menu_getmenuxy(NULL, &sx, &sy, NULL, NULL);
  917.     sx += ofsx;
  918.     sy += ofsy;
  919.     ARTputstr12(sx,sy,str,Cmenustring,Cmenu);
  920. }
  921.  
  922.  
  923. void    menu_buttonputstr(BUTTON *ip, int ofsx, int ofsy, char *str, int type)
  924. {
  925.     menu_putstr(ip->x+ofsx, ip->y+ofsy, str, type);
  926. }
  927.  
  928.  
  929. /*--------------------------------------------------------*/
  930. /*                  メニューの描画・消去                   */
  931. /*--------------------------------------------------------*/
  932.  
  933.  
  934. static    int        menuX_bk,menuY_bk;
  935. static    int        menuX0_bk,menuY0_bk;
  936. static    bool    subMenuDisp = NO;
  937. static    MENU    *cmenu_bk;
  938. static    char    *subm_scrbuf = NULL;
  939. static    MENU    *pre_menu = NULL;
  940.  
  941.  
  942. static void draw_shadedbox
  943.     (int x1,int y1,int xlen,int ylen,int col, int col_light, int col_shade,
  944.      bool f_frameonly, bool f_inverse)
  945. {
  946.     if (!f_frameonly)
  947.         grboxfill(x1,y1,xlen,ylen,col,DrawNORMAL);
  948.     ghline(x1,x1+xlen-1,y1+ylen-1,col_shade,DrawNORMAL);
  949.     gvline(x1+xlen-1,y1,y1+ylen-1,col_shade,DrawNORMAL);
  950.     ghline(x1,x1+xlen-(f_inverse?2:1),y1,col_light,DrawNORMAL);
  951.     gvline(x1,y1,y1+ylen-(f_inverse?2:1),col_light,DrawNORMAL);
  952. }
  953.  
  954.  
  955. static void draw_menubase(int x1, int y1, int xlen, int ylen, char *title)
  956. // タイトルバーつきメニュー枠の描画
  957. {
  958.     draw_shadedbox(x1,y1,xlen,ylen,ColM,ColL,ColS,NO,NO);
  959.     if (title != NULL && title[0] != '\0')
  960.     {
  961.         int tlen = 6 * strlen(title);
  962.         int l1,l2,l3,sx;
  963.         l2 = tlen+24;
  964.         l1 = ((xlen-2)-l2)/2;
  965.         l3 = (xlen-2)-(l1+l2);
  966.         sx = x1 + (xlen-tlen)/2;
  967.         draw_shadedbox(x1+1,y1+1,l1,16,ColM,ColL,ColS,YES,NO);
  968.         draw_shadedbox(x1+1+l1,y1+1,l2,16,ColM2,ColS,ColL,NO,YES);
  969.         draw_shadedbox(x1+1+l1+l2,y1+1,l3,16,ColM,ColL,ColS,YES,NO);
  970.         ARTputstr12(sx+1,y1+3,title,Cwhite,Cmenu);
  971.         ARTputstr12(sx,y1+3,title,Cmenushade,Cmenu);
  972.     }
  973.     else
  974.         draw_shadedbox(x1+1,y1+1,xlen-2,16,ColM,ColL,ColS,YES,NO);
  975. }
  976.  
  977.  
  978. void menu_drawbox(int x1, int y1, int xlen, int ylen)
  979. {
  980.     draw_shadedbox(x1,y1,xlen,ylen,ColM,ColL,ColS,YES,NO);
  981. }
  982.  
  983.  
  984. static void menu_dispbuttons(MENU *menu, BUTTON *ip)
  985. // list_method: 0=array  1=pointer-link-list
  986. {
  987.     PRINT("menu_dispbuttons begin\n");
  988.     int mx,my,mxlen,mylen;
  989.     menu_getmenuxy(menu, &mx, &my, &mxlen, &mylen);
  990.     int n;
  991.     for (n=0; ip!=NULL && ip->x>=0; ip++,n++)
  992.     {
  993.         PRINT("button static %d ",n);
  994.         switch (ip->type)
  995.         {
  996.         case typeBUTTONS:
  997.             PRINT("[BUTTONS]");
  998.             menu_dispbuttons(menu, (BUTTON*)ip->var);
  999.             break;
  1000.         case typePIC:
  1001.             PRINT("[PIC]");
  1002.             putpict(mx+ip->x, my+ip->y, ip->var);
  1003.             break;
  1004.         case typeSTR:    // 普通の文字列
  1005.         case typeSTRe:    // 太字文字列
  1006.         case typeSTRb:    // 箱入り文字列(ボタン用)
  1007.         case typeSTRc:  // センタリング立体強調文字列
  1008.             PRINT("[STR][%s]",(char*)ip->var);
  1009.             int sx,sy;
  1010.             sx = mx + ip->x;
  1011.             sy = my + ip->y;
  1012.             if (ip->type == typeSTRb)
  1013.             {
  1014.                 menu_drawbox(sx,sy,ip->xlen,ip->ylen);
  1015.                 sx+=4,sy+=2;
  1016.             }
  1017.             if (ip->type == typeSTRc)
  1018.             {
  1019.                 int len = 6 * strlen((char*)ip->var);
  1020.                 sx = mx + (mxlen - len)/2;
  1021.                 ARTputstr12(sx+1,sy,(char*)ip->var,Cwhite,Cmenu);
  1022.                 ARTputstr12(sx,sy,(char*)ip->var,Cmenushade,Cmenu);
  1023.             }
  1024.             else if (ip->type == typeSTRe)
  1025.             {
  1026.                 // ARTputstr12(sx+1,sy,(char*)ip->var,Cmenulight,Cmenu);
  1027.                 ARTputstr12(sx,sy,(char*)ip->var,Cmenustring,Cmenu);
  1028.             }
  1029.             else if ((char *)ip->var != NULL)
  1030.                 ARTputstr12(sx,sy,(char*)ip->var,Cmenustring,Cmenu);
  1031.             break;
  1032.         case typeBOX:
  1033.             PRINT("[BOX]");
  1034.             grboxfill(mx+ip->x,my+ip->y,ip->xlen,ip->ylen,
  1035.                       DMgetmenuplt(ip->var), DrawNORMAL);
  1036.             break;
  1037.         }
  1038.         if (ip->dspfunc != NOFNC)
  1039.             PRINT("[callfunc]");
  1040.         if (ip->dspfunc != NOFNC)
  1041.             (*ip->dspfunc)(mx+ip->x, my+ip->y);
  1042.         PRINT("\n",n);
  1043.     }
  1044.     PRINT("menu_dispbuttons end\n");
  1045. }
  1046.  
  1047.  
  1048. static void drawMenu_prim(void)
  1049. {
  1050.     PRINT("drawMenu_prim begin\n");
  1051.     int mx,my,mxlen,mylen;  MENU *menu;
  1052.     menu = menu_getcurmenu();
  1053.     KNOW(menu!=NULL);
  1054.     menu_getmenuxy(NULL, &mx, &my, &mxlen, &mylen);
  1055.     PRINT("mx:%d my:%d mxlen:%d mylen:%d\n",mx,my,mxlen,mylen);
  1056.     draw_menubase(mx,my,mxlen,mylen,menu->title);
  1057.     menu_dispbuttons(menu,menu->buttonlist);
  1058.     PRINT("メニュー描画中: ボタンリスト描画終了\n");
  1059.     SCROLLBAR *sp;
  1060.     for (sp = menu->sbarlist;  sp!=NULL && sp->x >= 0;  sp++)
  1061.         menu_drawscrollbar(sp);
  1062.     PRINT("メニュー描画中: スクロールバー描画終了\n");
  1063.     void dspsel(SEL *sel)
  1064.     {
  1065.         SELECTOR_ELEMENT *seli;
  1066.         for (seli = menu_selector_element_getfirst(sel);
  1067.              seli != NULL;
  1068.              seli = menu_selector_element_getnext(sel))
  1069.         {
  1070.             putpict(mx+seli->x, my+seli->y, Pselectoff);
  1071.            ARTputstr12(mx+seli->x+14,my+seli->y,seli->str,Cmenustring,Cmenu);
  1072.             if (! seli->available)
  1073.                 mist(mx+seli->x+14, my+seli->y, 6*strlen(seli->str),12, Cmenu);
  1074.         }
  1075.         seli = n2se(sel,sel->var);
  1076.         putpict(mx+seli->x, my+seli->y, Pselecton);
  1077.     }
  1078.     SELECTOR *sel;
  1079.     for (sel = menu->sellist;  sel!=NULL && sel->var >= 0;  sel++)
  1080.         dspsel(sel);
  1081.     for (sel = menu->d_sellist;  sel!=NULL;  sel=sel->next)
  1082.         dspsel(sel);
  1083.     PRINT("メニュー描画中: 選択子描画終了\n");
  1084.     if (menu->dspfunc != NOFNC)
  1085.         (*(menu->dspfunc))();
  1086.     PRINT("drawMenu_prim end\n");
  1087. }
  1088.  
  1089.  
  1090. int menu_dispxy(int x, int y, MENU *menu)
  1091. // (x,y):
  1092. //     メニューを表示する座標:メニュー左上 (特に指定しないときは -1)
  1093. //                                          (画面の真ん中に表示したいときは -2)
  1094. //                                    (メインメニューを最初に表示するときは -3)
  1095. // 返値: 0=成功 -1=メモリ不足
  1096. {
  1097.     int err=0;
  1098.     key_clrbuf();
  1099.  
  1100.     int __menu_x0, __menu_y0;
  1101.     PRINT("menu_dispxy begin\t[%s]\n", menu->title);
  1102.     // メニューリストのシフト
  1103.     int i;
  1104.     for (i=MENUNUM-1; i>=1; i--)
  1105.         menulist[i] = menulist[i-1];
  1106.     menulist[0] = menu;
  1107.     // メニュー座標の決定
  1108.     int zr = DMimage_getzoomrate();
  1109.     if (x >= 0)
  1110.         menu->x0 = x;
  1111.     else if (x == -2)
  1112.     {
  1113.         if (pre_menu != NULL && menu != pre_menu)
  1114.             __menu_x0 = pre_menu->x0;
  1115.         else
  1116.             __menu_x0 = menu->x0;
  1117.         menu->x0 = (DMgetxsize() - menu->xlen) / 2;
  1118.     }
  1119.     else if (x == -3)
  1120.     {
  1121.         __menu_x0 = menu->x0 = (DMgetxsize() - menu->xlen) / 2;
  1122.     }
  1123.     else
  1124.         if (pre_menu != NULL && menu != pre_menu)
  1125.             menu->x0 = pre_menu->x0;
  1126.     if (y >= 0)
  1127.         menu->y0 = y;
  1128.     else if (y == -2)
  1129.     {
  1130.         if (pre_menu != NULL && menu != pre_menu)
  1131.             __menu_y0 = pre_menu->y0;
  1132.         else
  1133.             __menu_y0 = menu->y0;
  1134.         menu->y0 = (DMgetysize() - menu->ylen) / 2;
  1135.     }
  1136.     else if (y == -3)
  1137.     {
  1138.         __menu_y0 = menu->y0 = (DMgetysize() - menu->ylen) / 2;
  1139.     }
  1140.     else
  1141.         if (pre_menu != NULL && menu != pre_menu)
  1142.             menu->y0 = pre_menu->y0;
  1143.     menu->x = (menu->x0 / zr) * zr;
  1144.     menu->y = (menu->y0 / zr) * zr;
  1145.     menu->x = _min(((DMgetxsize()-menu->xlen) / zr) * zr, menu->x);
  1146.     menu->y = _min(((DMgetysize()-menu->ylen) / zr) * zr, menu->y);
  1147.     menu->nobuf = NO;
  1148.     if (DMmenu1_addbox(menu->x,menu->y,menu->xlen,menu->ylen) != 0)
  1149.     {
  1150.         PRINT("メニュー表示域画像退避バッファ 確保失敗\n");
  1151.         menu->nobuf = YES;
  1152.         // // メニューリストのシフト(もとにもどす)
  1153.         // for (i=1; i<=MENUNUM-1; i++)
  1154.         //     menulist[i-1] = menulist[i];
  1155.         // menulist[MENUNUM-1] = NULL;
  1156.         // err = -1;
  1157.         // goto end_drawMenuTo;
  1158.     }
  1159.     else
  1160.         PRINT("メニュー表示域画像退避バッファ 確保成功\n");
  1161.     //
  1162.     drawMenu_prim();
  1163.     menu->display = YES;
  1164.  
  1165. end_drawMenuTo:
  1166.     if (x == -2)
  1167.         menu->x0 = __menu_x0;
  1168.     if (y == -2)
  1169.         menu->y0 = __menu_y0;
  1170.     pre_menu = menu;
  1171.     PRINT("menu_dispxy end  \t[%s]\n", menu->title);
  1172.     return err;
  1173. }
  1174.  
  1175.  
  1176. int menu_disp(MENU *menu)
  1177. {
  1178.     return menu_dispxy(-1, -1, menu);
  1179. }
  1180.  
  1181.  
  1182. void menu_erase()
  1183. {
  1184.     char menuname[100];  MENU *menu;  int i;
  1185.     menu = menulist[0];
  1186.     strcpy(menuname, menu->title);
  1187.     PRINT("menu_erase begin [%s]\n", menuname);
  1188.  
  1189.     menu->display = NO;
  1190.     if (menu->ersfunc != NOFNC)
  1191.         (*menu->ersfunc)();
  1192.     // menu_clearselector(menu);
  1193.     if (!menu->nobuf)
  1194.         DMmenu1_deletebox();
  1195.     // メニューリストのシフト
  1196.     for (i=1; i<=MENUNUM-1; i++)
  1197.         menulist[i-1] = menulist[i];
  1198.     menulist[MENUNUM-1] = NULL;
  1199.  
  1200.     PRINT("menu_erase end   [%s]\n", menuname);
  1201. }
  1202.  
  1203.  
  1204. /*--------------------------------------------------------*/
  1205. /*       メニューの描画・消去以外のメニュー関連処理       */
  1206. /*--------------------------------------------------------*/
  1207.  
  1208.  
  1209. void    menu_settitle(MENU *m, char *title)
  1210. {
  1211.     m->title = title;
  1212. }
  1213.  
  1214.  
  1215. int        menu_addselector(MENU *m, SEL *s)
  1216. {
  1217.     SEL *sp;
  1218.     s->next = NULL;
  1219.     if(m->d_sellist == NULL)
  1220.         m->d_sellist = s;
  1221.     else {
  1222.         for(sp=m->d_sellist;sp->next!=NULL;sp=sp->next)
  1223.             ;
  1224.         sp->next = s;
  1225.     }
  1226.     return 0;
  1227. }
  1228.  
  1229.  
  1230. void    menu_clearselector(MENU *m)
  1231. {
  1232.     SEL *psp,*sp;
  1233.     SEL_E *pep,*ep;
  1234.     for(psp=NULL,sp=m->d_sellist;sp!=NULL;psp=sp,sp=sp->next)
  1235.     {
  1236.         if(psp!=NULL) menu_selector_delete(psp);
  1237.         for(ep=sp->d_elist,pep=NULL;ep!=NULL;pep=ep,ep=ep->next)
  1238.         {
  1239.             if(pep!=NULL) menu_selector_element_delete(pep);
  1240.         }
  1241.         if(pep!=NULL) menu_selector_element_delete(pep);
  1242.         sp->d_elist = NULL;
  1243.     }
  1244.     if(psp!=NULL) menu_selector_delete(psp);
  1245.     m->d_sellist = NULL;
  1246. }
  1247.  
  1248.  
  1249. void menu_move()
  1250. {
  1251.     int zr = DMimage_getzoomrate();
  1252.     int dx,dy;  MENU *menu;
  1253.     menu = menu_getcurmenu();
  1254.     // ● 現在表示しているメニューの消去
  1255.     menu_erase();
  1256.     // ● 移動処理
  1257.     dx = ms.x - menu->x;
  1258.     dy = ms.y - menu->y;
  1259.     void drawcsr(int x,int y)
  1260.     {
  1261.         if (!DMgetifonepage())
  1262.             grboxline(x,y,menu->xlen,menu->ylen,DMgetmenuplt(csrcol),DrawXOR);
  1263.         else
  1264.             grboxline(x,y,menu->xlen,menu->ylen,DMgetmenuplt(White),DrawXOR);
  1265.     }
  1266.     while (ms.btn1==OFFON || ms.btn1==ON)
  1267.     {
  1268.         int prex,prey;
  1269.         DMdispcsr(ms.x,ms.y);
  1270.         prex=((ms.x-dx)/zr)*zr;
  1271.         prey=((ms.y-dy)/zr)*zr;
  1272.         drawcsr(prex,prey);
  1273.         do
  1274.         {
  1275.             ms_get(&ms);
  1276.         } while ((ms.btn1==OFFON||ms.btn1==ON) && ms.dx==0 && ms.dy==0 &&
  1277.                  key_chk()==0);
  1278.         DMerasecsr();
  1279.         drawcsr(prex,prey);        // 消去
  1280.         if (ms.x-dx < 0)
  1281.             ms.x = dx;
  1282.         else if (ms.x-dx+menu->xlen >= DMgetxsize())
  1283.             ms.x = DMgetxsize()-menu->xlen + dx;
  1284.         if (ms.y-dy < 0)
  1285.             ms.y = dy;
  1286.         else if (ms.y-dy+menu->ylen >= DMgetysize())
  1287.             ms.y = DMgetysize()-menu->ylen + dy;
  1288.     }
  1289.     menu->x0 = menu->x = ((ms.x-dx)/zr)*zr;
  1290.     menu->y0 = menu->y = ((ms.y-dy)/zr)*zr;
  1291.     // ● もと表示していたメニューの表示
  1292.     menu_disp(menu);
  1293. }
  1294.  
  1295.  
  1296. /*--------------------------------------------------------*/
  1297. /*      メニューに対する任意データの設定・取得・解除      */
  1298. /*--------------------------------------------------------*/
  1299.  
  1300.  
  1301. void menu_setdata(MENU *menu, void *data)
  1302. {
  1303.     if (menu == NULL)
  1304.         menu = menu_getcurmenu();
  1305.     menu->data = data;
  1306. }
  1307.  
  1308.  
  1309. void *menu_getdata(MENU *menu)
  1310. {
  1311.     if (menu == NULL)
  1312.         menu = menu_getcurmenu();
  1313.     return menu->data;
  1314. }
  1315.  
  1316.  
  1317. void menu_cleardata(MENU *menu)
  1318. {
  1319.     if (menu == NULL)
  1320.         menu = menu_getcurmenu();
  1321.     menu->data = NULL;
  1322. }
  1323.  
  1324.  
  1325. /* end of menu.c */
  1326.